package com.bkfm.framework.wf.service;

import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.yak.common.digest.DESUtils;
import org.yak.common.utils.RandomUtil;
import org.yak.core.exception.ServiceException;
import org.yak.core.service.BaseService;
import org.yak.core.utils.BeanUtils;
import org.yak.core.web.ResultSet;

import com.bkfm.framework.core.api.service.IBkfmTableMetaServer;
import com.bkfm.framework.core.constants.BkfmConstants;
import com.bkfm.framework.core.entity.BkfmDataRecord;
import com.bkfm.framework.core.entity.BkfmFilter;
import com.bkfm.framework.wf.api.service.IWorkFlowService;
import com.bkfm.framework.wf.api.store.IWorkFlowStore;
import com.bkfm.framework.wf.entity.BkfmDeployedWorkFlow;
import com.bkfm.framework.wf.entity.BkfmWorkFlow;
import com.bkfm.framework.wf.entity.BkfmWorkFlowForm;
import com.bkfm.framework.wf.entity.BkfmWorkFlowFormPageItem;
import com.bkfm.framework.wf.entity.BkfmWorkFlowFormPageItemAttr;
import com.bkfm.framework.wf.entity.BkfmWorkFlowFormPageItemHiddenField;
import com.bkfm.framework.wf.entity.BkfmWorkFlowFormPageItemPermis;
import com.bkfm.framework.wf.entity.BkfmWorkFlowFormPageItemReadOnlyField;
import com.bkfm.framework.wf.entity.BkfmWorkFlowLine;
import com.bkfm.framework.wf.entity.BkfmWorkFlowNode;
import com.bkfm.framework.wf.entity.BkfmWorkFlowNodePermisDept;
import com.bkfm.framework.wf.entity.BkfmWorkFlowNodePermisRole;
import com.bkfm.framework.wf.entity.BkfmWorkFlowNodePermisUser;
import com.bkfm.framework.wf.entity.BkfmWorkFlowTables;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

@Service
@Transactional
public class WorkFlowService extends BaseService<BkfmWorkFlow> implements IWorkFlowService{

	@Resource
	private IWorkFlowStore workFlowStore;
	
	@Resource
	private IBkfmTableMetaServer tableMetaService;
	
	/**
	 * 查询流程
	 */
	public BkfmWorkFlow queryWorkFlow(BkfmWorkFlow bkfmWorkFlow)throws Exception{
		BkfmFilter bkfmFilter = new BkfmFilter();
		bkfmFilter.setObj_path("ROOT/WORKFLOW/LCGL/BLK_WORKFLOW");
		bkfmFilter.setFilter("WORKFLOW_CODE='"+bkfmWorkFlow.getWorkflow_code()+"'");
		ResultSet resultSet = tableMetaService.queryTableModelMetaResultSet(bkfmFilter);
		BkfmWorkFlow newBkfmWorkFlow = (BkfmWorkFlow)resultSet.trans2Bean(BkfmWorkFlow.class);
		return newBkfmWorkFlow;
	}
	
	/**
	 * 保存设计流程
	 */
	public void saveWorkFlow(BkfmWorkFlow bkfmWorkFlow)throws Exception{
		BkfmFilter bkfmFilter = new BkfmFilter();
		bkfmFilter.setObj_path("ROOT/WORKFLOW/LCGL/BLK_WORKFLOW");
		bkfmFilter.setFilter("WORKFLOW_CODE='"+bkfmWorkFlow.getWorkflow_code()+"'");
		if(tableMetaService.checkNumber(bkfmFilter)>0) {
			//修改
			//解析流程json
			bkfmWorkFlow.setWorkflow_config(DESUtils.encryption(bkfmWorkFlow.getWorkflow_config()));
			JSONObject recordData = BeanUtils.trans2JSON(BeanUtils.trans2UpperMap(bkfmWorkFlow));
			BkfmDataRecord bkfmDataRecord = new BkfmDataRecord();
			bkfmDataRecord.setObj_path("ROOT/WORKFLOW/LCGL/BLK_WORKFLOW");
			bkfmDataRecord.setRecord_data(recordData.toString());
			bkfmDataRecord.setRecord_state(BkfmDataRecord.RECORD_STATE_CHANGED);
			bkfmDataRecord.setRwid(bkfmWorkFlow.getRwid());
			tableMetaService.modifyModelMetaData(bkfmDataRecord);
		}else {
			//新增
			bkfmWorkFlow.setWorkflow_config(DESUtils.encryption(bkfmWorkFlow.getWorkflow_config()));
			JSONObject recordData = BeanUtils.trans2JSON(BeanUtils.trans2UpperMap(bkfmWorkFlow));
			BkfmDataRecord bkfmDataRecord = new BkfmDataRecord();
			bkfmDataRecord.setObj_path("ROOT/WORKFLOW/LCGL/BLK_WORKFLOW");
			bkfmDataRecord.setRecord_data(recordData.toString());
			bkfmDataRecord.setRecord_state(BkfmDataRecord.RECORD_STATE_NEW);
			bkfmDataRecord.setRwid(bkfmWorkFlow.getRwid());
			tableMetaService.addModelMetaData(bkfmDataRecord);
		}
	}
	
	/**
	 * 部署流程
	 * @param bkfmWorkFlow
	 * @throws Exception
	 */
	public void deployWorkFlow(BkfmWorkFlow bkfmWorkFlow)throws Exception{
		bkfmWorkFlow = queryWorkFlow(bkfmWorkFlow);
		if(StringUtils.isEmpty(bkfmWorkFlow.getWorkflow_config())) {
			throw new ServiceException("没有配置流程信息");
		}
		Map<String, Class<?>> classMap = new HashMap<String, Class<?>>();
		classMap.put("workflow_nodes", BkfmWorkFlowNode.class);
		classMap.put("permis_users", BkfmWorkFlowNodePermisUser.class);
		classMap.put("permis_roles", BkfmWorkFlowNodePermisRole.class);
		classMap.put("permis_depts", BkfmWorkFlowNodePermisDept.class);
        classMap.put("workflow_lines", BkfmWorkFlowLine.class);  
        classMap.put("workflow_tables", BkfmWorkFlowTables.class); 
        classMap.put("workflow_forms", BkfmWorkFlowForm.class);
        classMap.put("workflow_form_pageitems", BkfmWorkFlowFormPageItem.class);
        classMap.put("readonlyfields", BkfmWorkFlowFormPageItemReadOnlyField.class);
        classMap.put("hiddenfields", BkfmWorkFlowFormPageItemHiddenField.class);
		BkfmDeployedWorkFlow newDeployWorkFlow = (BkfmDeployedWorkFlow)JSONObject.toBean(JSONObject.fromObject(DESUtils.decryption(bkfmWorkFlow.getWorkflow_config())), BkfmDeployedWorkFlow.class,classMap);
		
		
		//设置新的部署id
		newDeployWorkFlow.setRwid(RandomUtil.getRandom());
		//设置部署的流程配置文件
		newDeployWorkFlow.setWorkflow_config(bkfmWorkFlow.getWorkflow_config());
		newDeployWorkFlow.setDeployed_workflow_name(bkfmWorkFlow.getWorkflow_name());
		//保存部署流程
		BkfmDataRecord bkfmDataRecord = new BkfmDataRecord();
		bkfmDataRecord.setObj_path("ROOT/WORKFLOW/LCGL/BLK_WORKFLOW_DEPLOYED");
		bkfmDataRecord.setRecord_state(BkfmDataRecord.RECORD_STATE_NEW);
		bkfmDataRecord.setRwid(newDeployWorkFlow.getRwid());
		bkfmDataRecord.setRecord_data(BeanUtils.trans2JSON(BeanUtils.trans2UpperMap(newDeployWorkFlow)).toString());
		tableMetaService.addModelMetaData(bkfmDataRecord);
		//保存节点
		for(BkfmWorkFlowNode bkfmWorkFlowNode : newDeployWorkFlow.getWorkflow_nodes()) {
			bkfmWorkFlowNode.setRwid(RandomUtil.getRandom());
			bkfmWorkFlowNode.setWorkflow_deployed_id(newDeployWorkFlow.getRwid());
			bkfmDataRecord = new BkfmDataRecord();
			bkfmDataRecord.setObj_path("ROOT/WORKFLOW/LCGL/BLK_WORKFLOW_NODES");
			bkfmDataRecord.setRecord_state(BkfmDataRecord.RECORD_STATE_NEW);
			bkfmDataRecord.setRwid(bkfmWorkFlowNode.getRwid());
			bkfmDataRecord.setRecord_data(BeanUtils.trans2JSON(BeanUtils.trans2UpperMap(bkfmWorkFlowNode)).toString());
			tableMetaService.addModelMetaData(bkfmDataRecord);
			
			//保存节点用户操作权限
			for(BkfmWorkFlowNodePermisUser permisUser : bkfmWorkFlowNode.getPermis_users() ) {
				permisUser.setRwid(RandomUtil.getRandom());
				permisUser.setWorkflow_deployed_id(newDeployWorkFlow.getRwid());
				bkfmDataRecord = new BkfmDataRecord();
				bkfmDataRecord.setObj_path("ROOT/WORKFLOW/PERMIS/BLK_NODE_PERMIS_USERS");
				bkfmDataRecord.setRecord_state(BkfmDataRecord.RECORD_STATE_NEW);
				bkfmDataRecord.setRwid(permisUser.getRwid());
				bkfmDataRecord.setRecord_data(BeanUtils.trans2JSON(BeanUtils.trans2UpperMap(permisUser)).toString());
				tableMetaService.addModelMetaData(bkfmDataRecord);
			}
			//保存节点角色操作权限
			for(BkfmWorkFlowNodePermisRole permisRole : bkfmWorkFlowNode.getPermis_roles()) {
				permisRole.setRwid(RandomUtil.getRandom());
				permisRole.setWorkflow_deployed_id(newDeployWorkFlow.getRwid());
				bkfmDataRecord = new BkfmDataRecord();
				bkfmDataRecord.setObj_path("ROOT/WORKFLOW/PERMIS/BLK_NODE_PERMIS_ROLES");
				bkfmDataRecord.setRecord_state(BkfmDataRecord.RECORD_STATE_NEW);
				bkfmDataRecord.setRwid(permisRole.getRwid());
				bkfmDataRecord.setRecord_data(BeanUtils.trans2JSON(BeanUtils.trans2UpperMap(permisRole)).toString());
				tableMetaService.addModelMetaData(bkfmDataRecord);
			}
			//保存节点部门操作权限
			for(BkfmWorkFlowNodePermisDept permisDept : bkfmWorkFlowNode.getPermis_depts()) {
				permisDept.setRwid(RandomUtil.getRandom());
				permisDept.setWorkflow_deployed_id(newDeployWorkFlow.getRwid());
				bkfmDataRecord = new BkfmDataRecord();
				bkfmDataRecord.setObj_path("ROOT/WORKFLOW/PERMIS/BLK_NODE_PERMIS_DEPTS");
				bkfmDataRecord.setRecord_state(BkfmDataRecord.RECORD_STATE_NEW);
				bkfmDataRecord.setRwid(permisDept.getRwid());
				bkfmDataRecord.setRecord_data(BeanUtils.trans2JSON(BeanUtils.trans2UpperMap(permisDept)).toString());
				tableMetaService.addModelMetaData(bkfmDataRecord);
			}
		}
		
		//保留节点连接线
		for(BkfmWorkFlowLine bkfmWorkFlowLine : newDeployWorkFlow.getWorkflow_lines()) {
			bkfmWorkFlowLine.setRwid(RandomUtil.getRandom());
			bkfmWorkFlowLine.setWorkflow_deployed_id(newDeployWorkFlow.getRwid());
			bkfmDataRecord = new BkfmDataRecord();
			bkfmDataRecord.setObj_path("ROOT/WORKFLOW/LCGL/BLK_WORKFLOW_NODE_ACTIONS");
			bkfmDataRecord.setRecord_state(BkfmDataRecord.RECORD_STATE_NEW);
			bkfmDataRecord.setRwid(bkfmWorkFlowLine.getRwid());
			bkfmDataRecord.setRecord_data(BeanUtils.trans2JSON(BeanUtils.trans2UpperMap(bkfmWorkFlowLine)).toString());
			tableMetaService.addModelMetaData(bkfmDataRecord);
		}
		
		//保存流程所属业务表
		for(BkfmWorkFlowTables bkfmWorkFlowTable : newDeployWorkFlow.getWorkflow_tables()) {
			bkfmWorkFlowTable.setRwid(RandomUtil.getRandom());
			bkfmWorkFlowTable.setWorkflow_deployed_id(newDeployWorkFlow.getRwid());
			bkfmDataRecord = new BkfmDataRecord();
			bkfmDataRecord.setObj_path("ROOT/WORKFLOW/LCGL/BLK_WORKFLOW_TABLES");
			bkfmDataRecord.setRecord_state(BkfmDataRecord.RECORD_STATE_NEW);
			bkfmDataRecord.setRwid(bkfmWorkFlowTable.getRwid());
			bkfmDataRecord.setRecord_data(BeanUtils.trans2JSON(BeanUtils.trans2UpperMap(bkfmWorkFlowTable)).toString());
			tableMetaService.addModelMetaData(bkfmDataRecord);
		}
		//保存流程所属表单
		for(BkfmWorkFlowForm bkfmWorkFlowForm : newDeployWorkFlow.getWorkflow_forms()) {
			//保存表单
			bkfmWorkFlowForm.setRwid(RandomUtil.getRandom());
			bkfmWorkFlowForm.setWorkflow_deployed_id(newDeployWorkFlow.getRwid());
			bkfmDataRecord = new BkfmDataRecord();
			bkfmDataRecord.setObj_path("ROOT/WORKFLOW/LCGL/BLK_WORKFLOW_FORMS");
			bkfmDataRecord.setRecord_state(BkfmDataRecord.RECORD_STATE_NEW);
			bkfmDataRecord.setRwid(bkfmWorkFlowForm.getRwid());
			bkfmDataRecord.setRecord_data(BeanUtils.trans2JSON(BeanUtils.trans2UpperMap(bkfmWorkFlowForm)).toString());
			tableMetaService.addModelMetaData(bkfmDataRecord);
			
			//保存表单页面配置项
			for(BkfmWorkFlowFormPageItem bkfmWorkFlowFormPageItem : bkfmWorkFlowForm.getWorkflow_form_pageitems()) {
				bkfmWorkFlowFormPageItem.setRwid(RandomUtil.getRandom());
				bkfmWorkFlowFormPageItem.setWorkflow_deployed_id(newDeployWorkFlow.getRwid());
				bkfmDataRecord = new BkfmDataRecord();
				bkfmDataRecord.setObj_path("ROOT/WORKFLOW/LCGL/BLK_WORKFLOW_FORM_PAGECONFIGITEMS");
				bkfmDataRecord.setRecord_state(BkfmDataRecord.RECORD_STATE_NEW);
				bkfmDataRecord.setRwid(bkfmWorkFlowFormPageItem.getRwid());
				bkfmDataRecord.setRecord_data(BeanUtils.trans2JSON(BeanUtils.trans2UpperMap(bkfmWorkFlowFormPageItem)).toString());
				tableMetaService.addModelMetaData(bkfmDataRecord);
				
				//保存流程表单页面配制项属性
				BkfmWorkFlowFormPageItemAttr pageItemAttr = new BkfmWorkFlowFormPageItemAttr();
				pageItemAttr.setRwid(RandomUtil.getRandom());
				pageItemAttr.setPageconfigitem_rwid(bkfmWorkFlowFormPageItem.getRwid());
				pageItemAttr.setIs_save(bkfmWorkFlowFormPageItem.getIs_save());
				pageItemAttr.setIs_add(bkfmWorkFlowFormPageItem.getIs_add());
				pageItemAttr.setIs_edit(bkfmWorkFlowFormPageItem.getIs_edit());
				pageItemAttr.setIs_delete(bkfmWorkFlowFormPageItem.getIs_delete());
				pageItemAttr.setPageitem_height(bkfmWorkFlowFormPageItem.getPageitem_height());
				pageItemAttr.setPageitem_form_columncount(bkfmWorkFlowFormPageItem.getPageitem_form_columncount());
				bkfmDataRecord = new BkfmDataRecord();
				bkfmDataRecord.setObj_path("ROOT/WORKFLOW/LCGL/BLK_WORKFLOW_FORM_PAGECONFIGITEM_ATTR");
				bkfmDataRecord.setRecord_state(BkfmDataRecord.RECORD_STATE_NEW);
				bkfmDataRecord.setRwid(pageItemAttr.getRwid());
				bkfmDataRecord.setRecord_data(BeanUtils.trans2JSON(BeanUtils.trans2UpperMap(pageItemAttr)).toString());
				tableMetaService.addModelMetaData(bkfmDataRecord);
				
				
				//保存只读字段和隐藏字段
				BkfmWorkFlowFormPageItemPermis bkfmWorkFlowFormPageItemPermis = new BkfmWorkFlowFormPageItemPermis();
				bkfmWorkFlowFormPageItemPermis.setRwid(RandomUtil.getRandom());
				bkfmWorkFlowFormPageItemPermis.setPageconfigitem_rwid(bkfmWorkFlowFormPageItem.getRwid());
				//获取只读字段
				JSONArray readOnlyFieldArray = new JSONArray();
				for(BkfmWorkFlowFormPageItemReadOnlyField readOnlyField : bkfmWorkFlowFormPageItem.getReadonlyfields()) {
					readOnlyFieldArray.add(readOnlyField.getField_id());
				}
				bkfmWorkFlowFormPageItemPermis.setReadonly_fields(readOnlyFieldArray.toString());
				//获取隐藏字段
				JSONArray hiddenFieldArray = new JSONArray();
				for(BkfmWorkFlowFormPageItemHiddenField hiddenField : bkfmWorkFlowFormPageItem.getHiddenfields()) {
					hiddenFieldArray.add(hiddenField.getField_id());
				}
				bkfmWorkFlowFormPageItemPermis.setHidden_fields(hiddenFieldArray.toString());
				bkfmDataRecord = new BkfmDataRecord();
				bkfmDataRecord.setObj_path("ROOT/WORKFLOW/LCGL/BLK_WORKFLOW_FORM_PAGECONFIGITEM_PERMIS");
				bkfmDataRecord.setRecord_state(BkfmDataRecord.RECORD_STATE_NEW);
				bkfmDataRecord.setRwid(bkfmWorkFlowFormPageItemPermis.getRwid());
				bkfmDataRecord.setRecord_data(BeanUtils.trans2JSON(BeanUtils.trans2UpperMap(bkfmWorkFlowFormPageItemPermis)).toString());
				tableMetaService.addModelMetaData(bkfmDataRecord);
			}
		}
		
		if(StringUtils.isEmpty(bkfmWorkFlow.getIs_deployed()) || BkfmConstants.NO.equals(bkfmWorkFlow.getIs_deployed())) {
			//更新部署
			bkfmWorkFlow.setIs_deployed(BkfmConstants.YES);
			bkfmDataRecord = new BkfmDataRecord();
			bkfmDataRecord.setObj_path("ROOT/WORKFLOW/LCGL/BLK_WORKFLOW");
			bkfmDataRecord.setRecord_state(BkfmDataRecord.RECORD_STATE_NEW);
			bkfmDataRecord.setRwid(bkfmWorkFlow.getRwid());
			bkfmDataRecord.setRecord_data(BeanUtils.trans2JSON(BeanUtils.trans2UpperMap(bkfmWorkFlow)).toString());
			tableMetaService.modifyModelMetaData(bkfmDataRecord);
		}

	}
	
	/**
	 * 更新已部署的流程
	 * @param bkfmWorkFlow
	 * @throws Exception
	 */
	public void updateDeployWorkFlow(BkfmWorkFlow bkfmWorkFlow)throws Exception{
		
	}
}
